package design_pattern.FutureMode;

/**
 * @Author: 蔡翔
 * @Date: 2019/11/6 13:33
 * @Version 1.0
 * （重要）
 * 未来模式 也叫 传票模式 ：需要调用一个 执行很久的方法，先拿着发票，等我需要的时候再来拿。
 *
 * Future       ==》 代表的是未来的凭据
 * FutureTask   ==》 将你的调用逻辑进行一个隔离
 * FutureService ==》 桥接Future和FutureTask
 *
 *  超重点
 *
 * 进阶：回调函数的方式 来通知我。而并不是我阻塞在那里等、或者是其他轮询方式。
 */
public class SyncInvoker {
    //传统方式 1  通过Future get 方式取回调数据
    /*public static void main(String[] args) throws InterruptedException {
        FutureService futureService = new FutureService();
        //提交给future任务后，这里的future并不会阻塞在这里，只有future.get() 才会wait()住哪里 ，等待被唤醒。
        Future<String> future = futureService.submit(() -> {
            //这个接口函数，只是作为一个方法传入submit，但是它不是马上调用的。是在一个新的线程里面调用，也就是说并不是futureService来执行这个任务，而是futureService里面的一个子线程在执行。
            try {
                Thread.sleep(100001);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "Finished";
        });

        System.out.println("==============");
        System.out.println(" do other things");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("==============");
        //后期要通过future去获取 执行完任务后返回的值，如果还没执行好就 把这个线程（当前这个线程）wait住
        //如果当你提交的任务完成了，另外一个线程会监听到，然后会把这个线程唤醒，唤醒以后就接着wait后面，把result 给返回。
        System.out.println(future.get());
    }*/

    //方式2 ：回调方法，我好了来通知 你们
    public static void main(String[] args) throws InterruptedException {
        FutureService futureService = new FutureService();
        futureService.submit(() -> {
            try {
                Thread.sleep(100001);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "Finished";
        },s->{
            //这里只是对Consumer的一个实现，并不是 调用，什么时候调用等 consumer.accept();
            System.out.println(s);
            //这里是回调函数，我好了，就会去 回调这个函数 、、如写入数据库还是啥的你自己来。
        });
    }
    private static String get(){
        try {
            Thread.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "FINISH";
    }
}
